#include "Request.h" 
#include <mysql/mysql.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

MYSQL*		g_mysql		= NULL;
void	ad_init();
void	ad_init_config();
bool	connect_mysql();
bool	check_logon();
bool	request_handler(const char* name);

int main()
{
	setlocale(LC_ALL, "zh_CN.UTF-8");
	// 初始化环境
	ad_init();
	ad_init_config();
	// 等待用户接入
	while(FCGI_Accept() >= 0)
	{
		std::string		name;

		request::reset();
		// 判断数据库的连接性
		if(false == connect_mysql())
		{
			printf("Content-type: application/json\r\n"
					"\r\n"
					"{\r\n"
					"\t\"errno\":-1,\r\n"
					"\t\"error\":\"connect database failed\"\r\n"
					"}\r\n");
			continue;
		}

		// 获取请求名
		if( false == request::get("handler", name) )
		{
			printf("Content-type: application/json\r\n"
					"\r\n"
					"{\r\n"
					"\t\"errno\":-1,\r\n"
					"\t\"error\":\"invalid handler\"\r\n"
					"}\r\n");
			continue;
		}

		// 验证登录
		if( 0 != strcasecmp("login", name.c_str())
				&& 0 != strcasecmp("version", name.c_str())
				&& false == check_logon() )
		{
			printf("Content-type: application/json\r\n"
					"\r\n"
					"{\r\n"
					"\t\"errno\":-1,\r\n"
					"\t\"error\":\"time out\"\r\n"
					"}\r\n");
			continue;
		}

		// 执行请求
		if( false == request_handler(name.c_str()) )
		{
			printf("Content-type: application/json\r\n"
					"\r\n"
					"{\r\n"
					"\t\"errno\":-1,\r\n"
					"\t\"error\":\"not find handler\"\r\n"
					"}\r\n");
		}
	}

	return 0;
}

/*
 * 初始化
 */
void ad_init()
{
	char		path[1024]		= {0};
	char*		p;

	// 设置工作目录
	readlink("/proc/self/exe", path, sizeof(path));
	p = strrchr(path, '/');
	if(NULL != p)
	{
		*(p + 1) = 0;
		chdir(path);
	}
}

// 数据配置
static std::string		s_sql_server;
static std::string		s_sql_db;
static int				s_sql_port;
static std::string		s_sql_user;
static std::string		s_sql_passwd;

void parse_callback(const char* key, const char* value)
{
	if(0 == strcasecmp(key, "mysql_server"))
	{
		s_sql_server = value;
	}
	else if(0 == strcasecmp(key, "mysql_port"))
	{
		s_sql_port = atoi(value);
	}
	else if(0 == strcasecmp(key, "mysql_user"))
	{
		s_sql_user = value;
	}
	else if(0 == strcasecmp(key, "mysql_passwd"))
	{
		s_sql_passwd = value;
	}
	else if(0 == strcasecmp(key, "mysql_database"))
	{
		s_sql_db = value;
	}
}
/*
 * 初始化参数
 */
void ad_init_config()
{
	char*		buf;

	buf = sys::readFile("system.ini");
	if(NULL == buf)
	{
		return;
	}
	// 分析文件
	sys::parseConfig(buf, parse_callback);
	free(buf);
}

/*
 * 连接mysql
 */
bool connect_mysql()
{
	if(NULL != g_mysql)
	{
		if(0 == mysql_ping(g_mysql))
		{
			return true;
		}

		// 关闭原来的连接
		mysql_close(g_mysql);
	}
	else
	{
		g_mysql = (MYSQL *)malloc(sizeof(MYSQL));
	}

	// 初始化
	mysql_init(g_mysql);
	// 连接服务器
	if(NULL != mysql_real_connect(g_mysql, 
				s_sql_server.c_str(),
				s_sql_user.c_str(),
				s_sql_passwd.c_str(),
				s_sql_db.c_str(),
				s_sql_port,
				NULL, 0))
	{
		mysql_set_character_set(g_mysql, "utf8");
		return true;
	}

	free(g_mysql);
	g_mysql = NULL;
	return false;
}

/*
 * 检测是否登录
 */
bool check_logon()
{
	std::string		token;
	char*			ip		= getenv("REMOTE_ADDR");
	sql_string<>	sql;

	if(false == request::get("token", token)
			|| NULL == ip)
	{
		return false;
	}

	// 更新cookie
	sql.format("update t_session set active=now(),req = req + 1 where token='%q' "
			" and ip='%q' and date_add(active, interval 30 minute) > now() ",
			token.c_str(), ip);
	
	return sql::execute(sql.c_str()) > 0;
}
